package com.bookstore.service.impl;

import com.bookstore.dto.CategoryDTO;
import com.bookstore.entity.Category;
import com.bookstore.repository.CategoryRepository;
import com.bookstore.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    private CategoryRepository categoryRepository;

    @Override
    public List<CategoryDTO> getAllCategoriesAsTree() {
        // 获取所有顶级分类
        List<Category> parentCategories = categoryRepository.findAllParentCategories();
        
        // 转换为DTO并返回
        return parentCategories.stream()
                .map(CategoryDTO::fromEntity)
                .collect(Collectors.toList());
    }

    @Override
    public List<CategoryDTO> getAllParentCategories() {
        List<Category> parentCategories = categoryRepository.findAllParentCategories();
        return parentCategories.stream()
                .map(CategoryDTO::fromEntity)
                .collect(Collectors.toList());
    }

    @Override
    public CategoryDTO getCategoryById(Long id) {
        Category category = categoryRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("分类不存在"));
        return CategoryDTO.fromEntity(category);
    }

    @Override
    public List<CategoryDTO> getChildCategories(Long parentId) {
        List<Category> childCategories = categoryRepository.findByParentIdOrderByDisplayOrderAsc(parentId);
        return childCategories.stream()
                .map(CategoryDTO::fromEntity)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public CategoryDTO createCategory(CategoryDTO categoryDTO) {
        Category category = new Category();
        category.setCategoryName(categoryDTO.getCategoryName());
        category.setDescription(categoryDTO.getDescription());
        category.setDisplayOrder(categoryDTO.getDisplayOrder());
        category.setIcon(categoryDTO.getIcon());
        
        if (categoryDTO.getParentId() != null) {
            Category parent = categoryRepository.findById(categoryDTO.getParentId())
                    .orElseThrow(() -> new RuntimeException("父分类不存在"));
            category.setParent(parent);
        }
        
        Category savedCategory = categoryRepository.save(category);
        return CategoryDTO.fromEntity(savedCategory);
    }

    @Override
    @Transactional
    public CategoryDTO updateCategory(Long id, CategoryDTO categoryDTO) {
        Category category = categoryRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("分类不存在"));
        
        category.setCategoryName(categoryDTO.getCategoryName());
        category.setDescription(categoryDTO.getDescription());
        category.setDisplayOrder(categoryDTO.getDisplayOrder());
        category.setIcon(categoryDTO.getIcon());
        
        if (categoryDTO.getParentId() != null) {
            Category parent = categoryRepository.findById(categoryDTO.getParentId())
                    .orElseThrow(() -> new RuntimeException("父分类不存在"));
            category.setParent(parent);
        } else {
            category.setParent(null);
        }
        
        Category updatedCategory = categoryRepository.save(category);
        return CategoryDTO.fromEntity(updatedCategory);
    }

    @Override
    @Transactional
    public void deleteCategory(Long id) {
        Category category = categoryRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("分类不存在"));
        
        // 检查是否有子分类
        if (category.getChildren() != null && !category.getChildren().isEmpty()) {
            throw new RuntimeException("该分类下有子分类，无法删除");
        }
        
        // 检查是否有关联的图书
        if (category.getBooks() != null && !category.getBooks().isEmpty()) {
            throw new RuntimeException("该分类下有图书，无法删除");
        }
        
        categoryRepository.delete(category);
    }
}